package com.siteseat.common.foundation;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

import org.apache.commons.lang3.StringUtils;

import com.siteseat.common.exception.InternalException;
import com.siteseat.common.misc.FileHelper;

/**
 *
 */
public class PropertyHelper {

  /**
   * @param property
   * @param name
   */
  public static void ensureNotNull( ObjectLogger log, Object property, String name ) {
    if( log != null ) {
      log.info( name + "=" + String.valueOf( property ) );
    }
    if( property == null ) {
      throw new InternalException( "<" + name + "> property cannot be null" );
    }
  }
  
  /**
   * @param property
   * @param name
   */
  public static void ensureExists( ObjectLogger log, File property, String name, boolean isFolder ) {
    ensureNotNull( log, property, name );
    
    try {
      if( isFolder ) {
        FileHelper.validateFolder( property );
      } else {
        FileHelper.validateFile( property );
      }
    } catch( IOException e ) {
      throw new InternalException( "<" + name + "> property not properly set", e );
    }
  }

  /**
   * @param property
   * @param name
   */
  public static void ensureInitialized( ObjectLogger log, Object property, String name ) {
    ensureNotNull( log, property, name );
    if( property instanceof IComponent ) {
      if( ( (IComponent)property ).isInited() == false ) {
        throw new InternalException( "<" + name + "> property is not initialized yet" );
      }
    }
  }

  /**
   * @param property
   * @param name
   */
  public static void ensureNotInitialized( ObjectLogger log, Object property, String name ) {
    ensureNotNull( log, property, name );
    if( property instanceof IComponent ) {
      if( ( (IComponent)property ).isInited() == false ) {
        throw new InternalException( "<" + name + "> property is already initialized yet" );
      }
    }
  }

  /**
   * @param property
   * @param name
   */
  public static void ensureNotBlank( ObjectLogger log, String property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( StringUtils.isBlank( property ) ) {
      throw new InternalException( "<" + name + "> property cannot be blank" );
    }
  }

  /**
   * @param property
   * @param name
   */
  public static void ensureNotEmpty( ObjectLogger log, String property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( StringUtils.isEmpty( property ) ) {
      throw new InternalException( "<" + name + "> property cannot be empty" );
    }
  }

  /**
   * @param property
   * @param name
   */
  public static <T> void ensureHasElements( ObjectLogger log, Collection<T> property, String name ) {
    ensureNotNull( log, property, name );
    if( property.size() <= 0 ) {
      throw new InternalException( "<" + name + "> property must have elements" );
    }
  }

  /**
   * @param property
   * @param name
   */
  public static <T> void ensureHasElements( ObjectLogger log, T[] property, String name ) {
    ensureNotNull( log, property, name );
    if( property.length <= 0 ) {
      throw new InternalException( "<" + name + "> property must have elements" );
    }
  }
  
  /**
   * @param value
   * @param name
   */
  public static void ensurePositive( ObjectLogger log, long property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( property <= 0 ) {
      throw new InternalException( "<" + name + "> property must be > 0" );
    }
  }

  /**
   * @param value
   * @param name
   */
  public static void ensureGreaterThanOrEqualsTo( ObjectLogger log, int property, int expected, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( property < expected ) {
      throw new InternalException( "<" + name + "> property must be >= " + expected );
    }
  }

  /**
   * @param value
   * @param name
   */
  public static void ensureNegative( ObjectLogger log, long property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( property >= 0 ) {
      throw new InternalException( "<" + name + "> property must be < 0" );
    }
  }

  /**
   * @param value
   * @param name
   */
  public static void ensureNotPositive( ObjectLogger log, long property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( property > 0 ) {
      throw new InternalException( "<" + name + "> property must be <= 0" );
    }
  }

  /**
   * @param value
   * @param name
   */
  public static void ensureNotNegative( ObjectLogger log, long property, String name ) {
    if( log != null ) {
      log.info( name + "=" + property );
    }
    if( property < 0 ) {
      throw new InternalException( "<" + name + "> property must be >= 0" );
    }
  }

}
